/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.rationalsheet.parser.operation.function;

import org.rationalsheet.parser.expression.Expression;
import org.rationalsheet.parser.operation.Operation;
import org.rationalsheet.parser.operation.Operation;
import org.rationalsheet.parser.type.Type;

/**
 *
 * @author Overmind
 */
public abstract class Function
    extends Operation
{
    public static final String ARGUMENT_DELIMER = ",";
    public static final String OPEN_SCOPE = "(";
    public static final String CLOSE_SCOPE = ")";
    
    private String name;
    
    private static Expression buildExpression(String name, int argumentCount)
    {
        StringBuilder builder = new StringBuilder();
        
        builder.append(name);
        builder.append(OPEN_SCOPE);
        
        for(int i=0;i<argumentCount-1;++i)
        {
            builder.append(Expression.DEFAULT_ARGUMENT_SYMBOL);
            builder.append(ARGUMENT_DELIMER);
        }
        
        if(argumentCount > 0)
        {
            builder.append(Expression.DEFAULT_ARGUMENT_SYMBOL);
        }
        
        builder.append(CLOSE_SCOPE);
        
        return new Expression(builder.toString());
    }

    public Function(String name, Type resultType, Type[] argumentsType)
    {
        super(10, buildExpression(name, argumentsType.length) , resultType, argumentsType);
        this.name = name;
    } 
    
    public String getName()
    {
        return name;
    }

    @Override
    public String toString()
    {
        return super.toString(); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int compareTo(Operation right)
    {
        if(right instanceof Function)
        {
            Function function = (Function) right;
            
            int nameCompare = getName().compareTo(function.getName());
            
            if(nameCompare == 0)
            {
                int argumentsCountCompare = Integer.compare(getArgumentsCount(), function.getArgumentsCount());
                
                if(argumentsCountCompare == 0)
                {
                    for(int i=0;i<getArgumentsCount();++i)
                    {
                        int argumentCompare = getArgumentsType(i).compareTo(right.getArgumentsType(i));
                        
                        if(argumentCompare != 0)
                        {
                            return argumentCompare;
                        }
                    }
                    
                    return 0;
                }
                else
                {
                    return argumentsCountCompare;
                }
            }
            else
            {
                return nameCompare;
            }
        }
        else
        {
            return super.compareTo(right);
        }
    }
               
    
}
